/* eslint-disable react/prop-types */

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import CircleProgressBar from 'components/CircleProgressBar';

class CastViewer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loadModelStatus: '',
      loadModelProgress: 0,
    };
    this.onLoadComplete = this.onLoadComplete.bind(this);
    this.onLoadProgress = this.onLoadProgress.bind(this);
    this.onLoadError = this.onLoadError.bind(this);
    this.requestFullScreen = this.requestFullScreen.bind(this);
    this.requestReset = this.requestReset.bind(this);
  }

  onLoadComplete() {
    this.setState({ loadModelStatus: 'Complete' });
  }

  onLoadProgress(progress) {
    const progressValue = progress.loaded / progress.total;
    this.setState({ loadModelStatus: 'InProgress', loadModelProgress: progressValue });
  }

  onLoadError() {
    this.setState({ loadModelStatus: 'Error' });
  }

  isFullScreen() {
    return document.fullscreen
      || document.webkitIsFullScreen
      || document.mozFullScreen;
  }

  attachFullScreenEvents() {
    ['fullscreenchange',
      'webkitfullscreenchange',
      'mozfullscreenchange',
      'MSFullscreenChange',
    ].forEach((fsEventName) => {
      document.addEventListener(fsEventName, () => {
        if (this.isFullScreen()) {
          this.onFullScreenOpen();
        } else {
          this.onFullScreenClosed();
        }
      });
    });
  }

  onFullScreenOpen() {
    this.setState({
      isFullScreen: true,
    });
  }

  onFullScreenClosed() {
    this.setState({
      isFullScreen: false,
    });
  }

  requestFullScreen() {
    if (this.props.isMobile) {
      if (/work\/\S+\/detail\/embed/.test(this.props.location.pathname)) {
        this.props.router.push(`work/${this.props.params.workId}/detail`);
      } else {
        this.props.router.push(`/work/${this.props.params.workId}/detail/embed`);
      }
    } else {
      const viewport = this.viewport;
      if (viewport.requestFullscreen) {
        if (document.fullScreenElement) {
          document.cancelFullScreen();
        } else {
          viewport.requestFullscreen();
        }
      } else if (viewport.msRequestFullscreen) {
        if (document.msFullscreenElement) {
          document.msExitFullscreen();
        } else {
          viewport.msRequestFullscreen();
        }
      } else if (viewport.mozRequestFullScreen) {
        if (document.mozFullScreenElement) {
          document.mozCancelFullScreen();
        } else {
          viewport.mozRequestFullScreen();
        }
      } else if (viewport.webkitRequestFullscreen) {
        if (document.webkitFullscreenElement) {
          document.webkitCancelFullScreen();
        } else {
          viewport.webkitRequestFullscreen();
        }
      }
    }
  }

  requestReset() {
    const { castViewer } = this.state;
    castViewer.Reset();
  }

  componentDidUpdate() {
    const { isMobile } = this.props;
    if (isMobile) {
      document.title = 'VR中创建的全景3D大作是什么样的？';
    }
  }

  componentDidMount() {
    require.ensure([], (require) => {
      const castViewer = require('Cast/cast.index.js').default;
      this.setState({
        castViewer,
      });
      const castEventEmitter = require('Cast/cast.event.js').default;
      castEventEmitter.attachEvents('cast-viewport', castViewer);
      this.attachFullScreenEvents();
    });
  }

  render() {
    const progressStyle = { display: this.state.loadModelStatus === 'InProgress' ? 'block' : 'none' };
    const errorStyle = { display: this.state.loadModelStatus === 'Error' ? 'block' : 'none' };
    const { workInfo } = this.props;
    const { castViewer } = this.state;
    return (
      <div id="cast-viewport" className={this.state.isFullScreen ? 'fullscreen' : ''} ref={(input) => { this.viewport = input; }}>
        <button className="move">
          <i className="icon-black_move" onClick={this.requestReset} />
        </button>
        {!this.state.isFullScreen && <button className="full-screen" onClick={this.requestFullScreen}>
          <i className="icon-black_fullscreen" />
        </button>}
        {this.state.isFullScreen && <button className="full-screen" onClick={this.requestFullScreen}>
          <i className="icon-black_exit-fullscreen" />
        </button>}
        <div style={progressStyle} className="progress">
          <CircleProgressBar progress={this.state.loadModelProgress || 0} />
        </div>
        <div style={progressStyle} className="mask" />
        <div style={errorStyle} className="error">
          <icon className="icon-alert_small_error" />
          <p>加载模型失败，请尝试刷新浏览器</p>
        </div>
        {workInfo && workInfo.files && castViewer && <CastViewerLoader
          castViewer={castViewer}
          workInfo={workInfo}
          onLoadComplete={this.onLoadComplete}
          onLoadProgress={this.onLoadProgress}
          onLoadError={this.onLoadError}
        />}
      </div>
    );
  }
}

CastViewer.propTypes = {
  workInfo: PropTypes.object,
  isMobile: PropTypes.bool,
  router: PropTypes.object,
  params: PropTypes.object,
};

export default CastViewer;

// Fixme, nested component for lazy handling
class CastViewerLoader extends Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    const { castViewer, workInfo, onLoadComplete, onLoadProgress, onLoadError } = this.props;
    let webGlFileUrl = '';
    if (workInfo && workInfo.files) {
      const webglModelFile = workInfo.files.find(f => f.fileType === 'WEB_GL_MODEL');
      webGlFileUrl = webglModelFile ? webglModelFile.fileUrl : '';
    }
    castViewer.startRenderModel('cast-viewport', webGlFileUrl,
      {
        onLoadComplete,
        onLoadProgress,
        onLoadError,
      },
      {
        texturePath: './textures',
      },
    );
  }

  render() { return null; }
}
